package com.ruoyi.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.chat.LongConnection.model.ReceiveMsgVo;
import com.ruoyi.chat.LongConnection.model.ReturnMsgVo;
import com.ruoyi.chat.LongConnection.model.SendMsgVo;
import com.ruoyi.chat.LongConnection.model.msg.TextMsgVo;
import com.ruoyi.chat.LongConnection.util.LongConnectionMsgUtil;
import com.ruoyi.chat.LongConnection.util.LongConnectionUtil;
import com.ruoyi.chat.ab.entity.ChatRecord;
import com.ruoyi.chat.ab.service.IChatRecordService;
import com.ruoyi.chat.service.IChatService;
import com.ruoyi.framework.manager.AsyncManager;
import io.netty.channel.socket.SocketChannel;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TimerTask;
import java.util.concurrent.CountDownLatch;
import java.util.stream.Collectors;


@Service
public class ChatServiceImpl implements IChatService {
    @Autowired
    IChatRecordService chatrecordService;


    @Override
    public boolean sendMessageById(String receiverId, byte[] bytes) {
        if (LongConnectionUtil.checkIdWhetherOnline(receiverId)) {
            SocketChannel socketChannel = LongConnectionUtil.getChannelById(receiverId);
            socketChannel.writeAndFlush(LongConnectionMsgUtil.bytesToByteBuf(bytes));
        }

        return false;
    }


    @Override
    public List<ChatRecord> getAllUnReadMsg(String id) {
        QueryWrapper<ChatRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("if_read", "F").eq("receiver_id", id).select("receiver_id", "sender_id", "message", "msg_type", "rb", "CREATED_TIME", "msg_id").orderByAsc("CREATED_TIME");
        List<ChatRecord> list = chatrecordService.list(wrapper);
        List<ChatRecord> readedList = list.stream().map(c -> c.setIfRead("T")).collect(Collectors.toList());
        chatrecordService.updateBatchById(readedList);
        return list;
    }


    @Override
    public List<ChatRecord> getAllFriendsThreeHistoryChats(String id) {
        System.out.println("getAllFriendsThreeHistoryChats"+id);
        QueryWrapper<ChatRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("sender_id", id).select("receiver_id");
        List<ChatRecord> receiverList = chatrecordService.list(wrapper);
        wrapper.clear();
        wrapper.eq("receiver_id", id).select("sender_id");
        List<ChatRecord> senderList = chatrecordService.list(wrapper);

        Set<String> set = receiverList.stream().map(ChatRecord::getReceiverId).collect(Collectors.toSet());
        senderList.stream().map(ChatRecord::getReceiverId).forEach(set::add);
        //System.out.println(set);
        final CountDownLatch latch = new CountDownLatch(set.size());
        List<ChatRecord> rs = new ArrayList<>();

        for (String item :
                set) {
            AsyncManager.me().execute(new TimerTask() {
                @SneakyThrows
                @Override
                public void run() {
                    QueryWrapper<ChatRecord> wrapper1 = new QueryWrapper<>();
                    wrapper1.eq("receiver_id", item).and(i -> i.eq("sender_id", id)).or().eq("sender_id", item).and(i -> i.eq("receiver_id", id)).
                            select("receiver_id", "sender_id", "message", "msg_type", "rb", "CREATED_TIME", "msg_id").orderByDesc("CREATED_TIME").last("limit 10");
                    List<ChatRecord> list = chatrecordService.list(wrapper1);
                    rs.addAll(list);
                    latch.countDown();
                }
            });
        }
        try {
            latch.await();
        }catch (Exception e){
        }
        return rs;
    }


    @Override
    public List<ChatRecord> getFiveHisChats(String msgId, String user1, String user2) {
        //System.out.println(user1 + "" + user2);
        chatrecordService.save(new ChatRecord().setMessage("text"));
        chatrecordService.list();
        LocalDateTime lastTime = chatrecordService.getById(msgId).getCreatedTime();
        QueryWrapper<ChatRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("receiver_id", user1).and(i -> i.eq("sender_id", user2)).
                le("CREATED_TIME", lastTime).and(i -> i.ne("msg_id", msgId)).select("receiver_id", "sender_id", "message", "msg_type", "rb", "CREATED_TIME", "msg_id")
                .orderByDesc("CREATED_TIME").last("limit 5");
        List<ChatRecord> list = chatrecordService.list(queryWrapper);

        queryWrapper.clear();
        queryWrapper.eq("sender_id", user1).and(i -> i.eq("receiver_id", user2)).
                le("CREATED_TIME", lastTime).and(i -> i.ne("msg_id", msgId)).select("receiver_id", "sender_id", "message", "msg_type", "rb", "CREATED_TIME", "msg_id")
                .orderByDesc("CREATED_TIME").last("limit 5");

        list.addAll(chatrecordService.list(queryWrapper));
        //System.out.println(list);
        return list;
    }

    @Override
    public List<ChatRecord> getHisChatsBetweenDate(String Id, String Id2, LocalDateTime bg, LocalDateTime ed) {
        QueryWrapper<ChatRecord> wrapper = new QueryWrapper<>();
        wrapper.eq("sender_id", Id).and(i -> i.eq("receiver_id", Id2)).le("CREATED_TIME", ed).ge("CREATED_TIME", bg)
                .select("receiver_id", "sender_id", "message", "msg_type", "rb", "CREATED_TIME", "msg_id");
        List<ChatRecord> list = chatrecordService.list(wrapper);

        wrapper.clear();
        wrapper.eq("receiver_id", Id).and(i -> i.eq("sender_id", Id2)).le("CREATED_TIME", ed).ge("CREATED_TIME", bg)
                .select("receiver_id", "sender_id", "message", "msg_type", "rb", "CREATED_TIME", "msg_id");
        list.addAll(chatrecordService.list(wrapper));
        return list;
    }
}
